﻿using System;
using System.Collections.Generic;
using System.Text;

namespace NFinal.Tools
{
    /// <summary>
    /// 字符串与数字互转
    /// </summary>
    public class CharsConvert
    {
        private char[] usedChars;
        private int bitLength = 0;
        private Dictionary<char, int> charsAt = null;

        private string maxChars;

        /// <summary>
        /// 初始化,用到的字符
        /// </summary>
        /// <param name="usedChars"></param>
        public CharsConvert(string usedChars = null)
        {
            if (usedChars == null)
            {
                usedChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890()_~[];\'.+-*";
            }
            this.usedChars = usedChars.ToCharArray();
            this.bitLength = usedChars.Length;
            charsAt = new Dictionary<char, int>(this.bitLength);
            for (int i = 0; i < usedChars.Length; i++)
            {
                charsAt[usedChars[i]] = i;
            }
            this.maxChars = GetChars(long.MaxValue);
        }

        /// <summary>
        /// 输入字符串是否合规
        /// </summary>
        /// <param name="chars"></param>
        /// <returns></returns>
        private bool IsValidChars(string chars)
        {
            int len = chars.Length - this.maxChars.Length;
            if (len < 0)
            {
                return true;
            }
            else if (len > 0)
            {
                return false;
            }
            else
            {
                int maxIndex = 0;
                int charIndex = 0;
                for (int i = 0; i < maxChars.Length; i++)
                {
                    if (charsAt.ContainsKey(maxChars[i]))
                    {
                        maxIndex = charsAt[maxChars[i]];
                        charIndex = charsAt[chars[i]];
                        if (maxIndex > charIndex)
                        {
                            return true;
                        }
                        else if (maxIndex == charIndex)
                        {
                            continue;
                        }
                        else
                        {
                            return false;
                        }
                    }
                    else
                    {
                        return false;
                    }
                }
            }
            return true;
        }

        /// <summary>
        /// 把数字转为字符串
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        public string GetChars(long num)
        {
            if (num < 0)
            {
                return null;
            }
            long indexNum = 0;
            Stack<char> chars = new Stack<char>();
            while (num >= bitLength)
            {
                indexNum = num % bitLength;
                num = num / bitLength;
                chars.Push(usedChars[indexNum]);
            }
            chars.Push(usedChars[num]);
            return string.Join("", chars);
        }

        /// <summary>
        /// 把字符串转为数字
        /// </summary>
        /// <param name="chars"></param>
        /// <returns></returns>
        public long GetNum(string chars)
        {
            if (IsValidChars(chars))
            {
                int j = 0;
                long num = 0;
                long temp = 0;
                for (int i = chars.Length - 1; i >= 0; i--)
                {
                    temp = (long)Math.Pow(bitLength, j);
                    j++;
                    num = num + temp * charsAt[chars[i]];
                }
                return num;
            }
            else
            {
                return 0;
            }
        }
    }
}
